
package com.ctrip.corp.obt.shard.sql.mybatis.interceptor.compatibility;

import java.util.EnumMap;
import java.util.Map;

import com.ctrip.corp.obt.generic.utils.ExceptionUtils;
import com.ctrip.corp.obt.shard.constants.DbType;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.dialect.DmDialect;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.dialect.IDialect;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.dialect.KingBaseDialect;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.dialect.MySqlDialect;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.dialect.OracleDialect;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.dialect.PostgreDialect;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.dialect.SQLServerDialect;

/**
 * 信创兼容工厂类
 *
 * @author marco.zheng
 * @since 2022-03-15
 */
public class CompatibilityFactory {
    private static final Map<DbType, IDialect> DIALECT_ENUM_MAP = new EnumMap<>(DbType.class);

    public static IDialect getDialect(DbType dbType) {
        return DIALECT_ENUM_MAP.computeIfAbsent(dbType, CompatibilityFactory::createByDbType);
    }

    private static IDialect createByDbType(DbType dbType) {
        IDialect dialect = null;
        if (dbType == DbType.OTHER) {
            throw ExceptionUtils.mpe("%s database not supported.", dbType.getDb());
        }
        // mysql same type
        else if (dbType == DbType.MYSQL
            || dbType == DbType.MARIADB) {
            dialect = new MySqlDialect();
        }
        // oracle same type
        else if (dbType == DbType.ORACLE) {
            dialect = new OracleDialect();
        }
        // postgresql same type
        else if (dbType == DbType.POSTGRE_SQL
            || dbType == DbType.H2
            || dbType == DbType.SQLITE
            || dbType == DbType.PHOENIX) {
            dialect = new PostgreDialect();
        } else if (dbType == DbType.SQL_SERVER) {
            dialect = new SQLServerDialect();
        }
        // kingbase
        else if (dbType == DbType.KINGBASE) {
            dialect = new KingBaseDialect();
        }
        // dm
        else if (dbType == DbType.DM) {
            dialect = new DmDialect();
        }
        return dialect;
    }
}
